<script lang="ts" setup>
import { UploadOutlined } from '@ant-design/icons-vue'
import type { UploadProps } from 'ant-design-vue'
import { message } from 'ant-design-vue'
import { reactive, ref } from 'vue'
import { useI18n } from 'vue-i18n'
import { api } from '@/api'

const ALLOW_FILE_TYPE = ['xml', 'zip']

const { t } = useI18n()
const modalState = reactive({
  visible: false,
  isLoading: false,
  isAffected: false,
  uploading: false,
})

// #region ----------------------------------------< upload file >----------------------------------------
const fileList = ref<UploadProps['fileList']>([])

const removeFile: UploadProps['onRemove'] = (file) => {
  if (!fileList.value)
    return
  const index = fileList.value.indexOf(file)
  const newFileList = fileList.value.slice()
  newFileList.splice(index, 1)
  fileList.value = newFileList
}

/**
 * examine file before upload
 * @param file
 */
const preUpload: UploadProps['beforeUpload'] = async (file) => {
  const fileType = file.name.split('.')[1]
  if (!ALLOW_FILE_TYPE.includes(fileType)) {
    message.error(t('vul.sentence.fileType'))
    setTimeout(() => {
      removeFile(file)
    }, 0)
    return false
  }

  const fileSize = file.size
  if (fileSize > 1024 * 1024 * 20) {
    message.error(t('vul.sentence.fileSize'))
    setTimeout(() => {
      removeFile(file)
    }, 0)
    return false
  }
  fileList.value = [file]

  return false
}

async function upload() {
  const formData = new FormData()
  fileList.value?.forEach((file) => {
    formData.append('file', file as any)
  })
  modalState.uploading = true
  if (modalState.isAffected) {
    const [_] = await api.uploadSAAffected(formData)
    if (!_)
      message.success(t('common.uploadSuccess'))
  }
  else {
    const [_] = await api.uploadSAUnAffected(formData)
    if (!_)
      message.success(t('common.uploadSuccess'))
  }
  modalState.uploading = false
  modalState.visible = false
  fileList.value?.forEach((file) => {
    removeFile(file)
  })
}

// #endregion

/**
 * close modal
 */
function handleClose() {
  modalState.visible = false
}
</script>

<template>
  <div class="upload-sa">
    <div @click="modalState.visible = true">
      <slot name="trigger" />
    </div>
    <a-modal
      v-model:open="modalState.visible"
      :title="$t('vul.uploadFile')"
      :footer="null"
      destroy-on-close
      @cancel="handleClose"
    >
      <a-upload :file-list="fileList" :before-upload="preUpload" @remove="removeFile">
        <a-row type="flex" class="upload" :gutter="24">
          <a-col>
            <a-button>
              <UploadOutlined />
              {{ $t('common.selectDoc') }}
            </a-button>
          </a-col>
          <a-col class="upload-type">
            <div>{{ $t('vul.sa.fileType') }}</div>
            <div>{{ $t('vul.sa.fileSize') }}</div>
          </a-col>
        </a-row>
      </a-upload>
      <a-radio-group
        v-model:value="modalState.isAffected"
        name="radioGroup"
        style="margin-top: 20px"
      >
        <a-radio :value="false">
          {{ $t('vul.unaffected') }}
        </a-radio>
        <a-radio :value="true">
          {{ $t('vul.affected') }}
        </a-radio>
      </a-radio-group>
      <a-button
        type="primary"
        :disabled="fileList!.length === 0"
        :loading="modalState.uploading"
        style="display: block; margin-top: 20px"
        @click="upload"
      >
        {{ modalState.uploading ? t('common.uploading') : t('common.upload') }}
      </a-button>
    </a-modal>
  </div>
</template>

<style lang="less" scoped>
.upload {
  display: flex;
  align-items: center;
}
</style>
